<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="关键词" prop="cond">
        <el-input v-model="queryParams.cond" placeholder="请输入关键词搜索" ref="cond" clearable @keyup.enter.native="handleQuery"/>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" class="search-btn" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" class="reset-btn" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" icon="el-icon-plus" size="mini" class="action-button add-btn" @click="handleAdd" v-hasPermi="['data:struct:add']">新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="info" icon="el-icon-sort" size="mini" class="action-button expand-btn" @click="toggleExpandAll">{{ isExpandAll ? '折叠' : '展开' }}</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="success" icon="el-icon-magic-stick" size="mini" class="action-button extract-btn" @click="openExtractRequirementsDialog">提取需求</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table
      v-if="refreshTable"
      v-loading="loading"
      :data="structList"
      row-key="id"
      :default-expand-all="isExpandAll"
      :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
      class="tree-table"
      :row-class-name="rowClassName">
      <el-table-column label="名称" prop="name" min-width="100">
        <template slot-scope="scope">
          <span class="tree-node-name">
            <i :class="scope.row.isdir === 'Y' ? 'el-icon-folder' : 'el-icon-document'" class="node-icon"></i>
            {{ scope.row.name }}
          </span>
        </template>
      </el-table-column>
      <el-table-column label="编码" align="left" prop="code" min-width="50"/>
      <el-table-column label="挂载数据" align="center" min-width="70">
        <template slot-scope="scope">
          <div class="mount-data">
            <!-- 挂载链接按钮 -->
            <div class="mount-links">
              <a href="javascript:;" class="link-text mount-link" @click="handleMountDemand(scope.row)">
                <i class="el-icon-connection"></i>挂载需求
              </a>
              <span class="link-divider">|</span>
              <a href="javascript:;" class="link-text mount-link-tech" @click="handleMountTechnical(scope.row)">
                <i class="el-icon-connection"></i>挂载技术指标
              </a>
            </div>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" min-width="100" class-name="small-padding fixed-width operation-column">
        <template slot-scope="scope">
          <div class="table-operation">
            <a href="javascript:;" class="link-text edit-link" @click="handleUpdate(scope.row)">
              <i class="el-icon-edit"></i>修改
            </a>
            <span class="link-divider">|</span>

            <!-- 使用占位符保持对齐 -->
            <template v-if="scope.row.isdir === 'Y'">
              <a href="javascript:;" class="link-text add-link" @click="handleAdd(scope.row)">
                <i class="el-icon-plus"></i>新增
              </a>
            </template>
            <template v-else>
              <span class="empty-placeholder"></span>
            </template>

            <span class="link-divider">|</span>
            <a href="javascript:;" class="link-text delete-link" @click="handleDelete(scope.row)">
              <i class="el-icon-delete"></i>删除
            </a>
          </div>
        </template>
      </el-table-column>
    </el-table>

    <!-- 添加或修改高速列车结构对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body class="struct-dialog">
      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="上级结构" prop="pid" class="form-item-spaced">
          <treeselect v-model="form.pid" :options="structOptions" :normalizer="normalizer" placeholder="请选择上级结构"/>
        </el-form-item>
        <el-form-item label="编码" prop="code" class="form-item-spaced">
          <el-input v-model="form.code" ref="code" placeholder="请输入编码"/>
        </el-form-item>
        <el-form-item label="名称" prop="name" class="form-item-spaced">
          <el-input v-model="form.name" placeholder="请输入名称"/>
        </el-form-item>
        <el-form-item label="是否为目录" prop="isdir" class="form-item-spaced">
          <el-radio-group v-model="form.isdir">
            <el-radio label="Y">是</el-radio>
            <el-radio label="N">否</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="同级顺序" prop="tseq" class="form-item-spaced">
          <el-input-number v-model="form.tseq" placeholder="请输入同级顺序" min="1"/>
        </el-form-item>
        <el-form-item label="备注" prop="remark" class="form-item-spaced">
          <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"/>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 挂载需求对话框 -->
    <el-dialog title="挂载需求" :visible.sync="mountDemandOpen" width="70%" append-to-body class="demand-dialog">
      <div class="dialog-container">
        <!-- 显示当前正在为哪个节点挂载需求 -->
        <div class="dialog-target">
          <span class="target-label">挂载到:</span>
          <span class="target-node">{{ currentMountNode && currentMountNode.name || '未选择节点' }}</span>
        </div>

        <div class="dialog-content">
          <el-row :gutter="20" style="height: 100%;">
            <!-- 左侧需求树 -->
            <el-col :span="8" class="tree-container">
              <div class="panel-container">
                <div class="panel-header">需求列表</div>
                <div class="search-box">
                  <el-input v-model="filterDemandText"
                            placeholder="请输入需求名称"
                            clearable
                            size="small"
                            prefix-icon="el-icon-search"
                            @input="filterDemandTreeNodes" />
                </div>
                <div class="panel-body" v-loading="demandTreeLoading">
                  <el-tree
                    :data="demandTree"
                    :props="defaultProps"
                    :expand-on-click-node="false"
                    :filter-node-method="filterDemandNode"
                    ref="demandTree"
                    node-key="id"
                    default-expand-all
                    highlight-current
                    @node-click="handleDemandNodeClick">
                    <span class="tree-node-name" slot-scope="{ node, data }">
                      <i :class="data.isdir === 'Y' ? 'el-icon-folder' : 'el-icon-document'" class="node-icon"></i>
                      {{ node.label }}
                    </span>
                  </el-tree>
                </div>
              </div>
            </el-col>

            <!-- 右侧已挂载需求表格 -->
            <el-col :span="16" class="table-container">
              <div class="panel-container">
                <div class="panel-header">已挂载需求</div>
                <div class="panel-body">
                  <el-table
                    :data="structDemandList"
                    border
                    style="width: 100%"
                    v-loading="demandTableLoading"
                    height="calc(100% - 20px)">
                    <el-table-column prop="name" label="需求名称" min-width="200" show-overflow-tooltip></el-table-column>
                    <el-table-column label="需求类型" width="100">
                      <template slot-scope="scope">
                        <template v-if="scope.row.type === 'text'">
                          <el-tag type="success" size="mini">文本</el-tag>
                        </template>
                        <template v-else-if="scope.row.type === 'num'">
                          <el-tag type="primary" size="mini">数字</el-tag>
                        </template>
                        <template v-else-if="scope.row.type === 'range'">
                          <el-tag type="warning" size="mini">范围</el-tag>
                        </template>
                        <template v-else-if="scope.row.type === 'option'">
                          <el-tag type="info" size="mini">选项</el-tag>
                        </template>
                        <template v-else>
                          <span>-</span>
                        </template>
                      </template>
                    </el-table-column>
                    <el-table-column label="需求值" min-width="150" show-overflow-tooltip>
                      <template slot-scope="scope">
                        <template v-if="scope.row.type === 'text' || scope.row.type === 'num'">
                          <el-tooltip placement="top"
                                     :content="scope.row.values && scope.row.values[0] ? scope.row.values[0].value : '暂无内容'"
                                     :disabled="!scope.row.values || !scope.row.values[0]"
                                     popper-class="content-tooltip">
                            <div class="value-wrapper">
                              <span class="text-value">{{ scope.row.values && scope.row.values[0] ? scope.row.values[0].value : '-' }}</span>
                            </div>
                          </el-tooltip>
                        </template>
                        <template v-else-if="scope.row.type === 'option'">
                          <el-tooltip placement="top"
                                     :content="getOptionsTooltip(scope.row)"
                                     :disabled="!scope.row.values || scope.row.values.length === 0"
                                     popper-class="content-tooltip">
                            <div class="value-wrapper">
                              <span class="count-value">
                                <i class="el-icon-collection-tag"></i> {{ getOptionsCount(scope.row) }}个选项
                              </span>
                            </div>
                          </el-tooltip>
                        </template>
                        <template v-else-if="scope.row.type === 'range'">
                          <el-tooltip placement="top"
                                     :content="getRangeTooltip(scope.row)"
                                     :disabled="!scope.row.values || scope.row.values.length === 0"
                                     popper-class="content-tooltip">
                            <div class="value-wrapper">
                              <span class="count-value">
                                <i class="el-icon-data-line"></i> {{ getRangeCount(scope.row) }}个范围
                              </span>
                            </div>
                          </el-tooltip>
                        </template>
                        <template v-else>
                          <div class="value-wrapper">
                            <span class="empty-value">-</span>
                          </div>
                        </template>
                      </template>
                    </el-table-column>
                    <el-table-column label="操作" width="150" align="center" fixed="right" class-name="operation-column">
                      <template slot-scope="scope">
                        <!-- 修改条件，允许text、option和range类型显示编辑按钮 -->
                        <el-button
                          v-if="scope.row.type === 'text' || scope.row.type === 'option' || scope.row.type === 'range'"
                          size="mini"
                          type="text"
                          icon="el-icon-edit"
                          class="edit-text-btn"
                          @click="handleEditDemand(scope.row)">编辑</el-button>
                        <el-button
                          size="mini"
                          type="text"
                          icon="el-icon-delete"
                          class="delete-text-btn"
                          @click="handleRemoveDemand(scope.row)">移除</el-button>
                      </template>
                    </el-table-column>
                  </el-table>
                </div>
              </div>
            </el-col>
          </el-row>
        </div>

        <div slot="footer" class="dialog-footer">
          <el-button @click="mountDemandOpen = false" class="dialog-btn cancel-btn">取 消</el-button>
        </div>
      </div>
    </el-dialog>

    <!-- 挂载技术指标对话框 -->
    <el-dialog title="挂载技术指标" :visible.sync="mountIndOpen" width="70%" append-to-body class="demand-dialog">
      <div class="dialog-container">
        <!-- 显示当前正在为哪个节点挂载技术指标 -->
        <div class="dialog-target">
          <span class="target-label">挂载到:</span>
          <span class="target-node">{{ currentMountNode && currentMountNode.name || '未选择节点' }}</span>
        </div>

        <!-- 添加标准选择区域 -->
        <div class="standard-selection">
          <div class="standard-header">
            <span class="standard-label">选择标准:</span>
            <el-select v-model="selectedStandard" placeholder="请选择适用的技术标准" style="width: 350px;" clearable>
              <el-option v-for="item in standardOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
            </el-select>

            <!-- 添加自定义标准上传选项 -->
            <span class="standard-divider">或</span>
            <el-upload
              class="custom-standard-upload"
              action="#"
              :http-request="uploadCustomStandard"
              :before-upload="beforeCustomStandardUpload"
              :show-file-list="false">
              <el-button size="small" type="primary" plain>
                <i class="el-icon-upload2"></i> 上传企业标准
              </el-button>
            </el-upload>

            <el-button type="primary" size="small" class="check-btn" @click="checkNonStandardIndicators" :disabled="!hasValidStandard || structIndList.length === 0" :loading="checkingIndicators">
              <i class="el-icon-check"></i> 检查非标指标
            </el-button>
          </div>

          <!-- 显示当前使用的自定义标准 -->
          <div v-if="customStandard" class="custom-standard-info">
            <div class="standard-file-info">
              <i class="el-icon-document"></i>
              <span class="file-name">{{ customStandard.name }}</span>
              <span class="file-size">({{ formatFileSize(customStandard.fileSize) }})</span>
              <el-tag size="mini" type="success">自定义标准</el-tag>
            </div>
            <div class="standard-actions">
              <el-button type="text" size="mini" @click="viewCustomStandard">
                <i class="el-icon-view"></i> 查看内容
              </el-button>
              <el-button type="text" size="mini" @click="removeCustomStandard">
                <i class="el-icon-delete"></i> 移除
              </el-button>
            </div>
          </div>
        </div>

        <div class="dialog-content">
          <el-row :gutter="20" style="height: 100%;">
            <!-- 左侧技术指标树 -->
            <el-col :span="8" class="tree-container">
              <div class="panel-container">
                <div class="panel-header">技术指标列表</div>
                <div class="search-box">
                  <el-input v-model="filterIndText"
                            placeholder="请输入技术指标名称"
                            clearable
                            size="small"
                            prefix-icon="el-icon-search"
                            @input="filterIndTreeNodes" />
                </div>
                <div class="panel-body" v-loading="indTreeLoading">
                  <el-tree
                    :data="indTree"
                    :props="defaultProps"
                    :expand-on-click-node="false"
                    :filter-node-method="filterIndNode"
                    ref="indTree"
                    node-key="id"
                    default-expand-all
                    highlight-current
                    @node-click="handleIndNodeClick">
                    <span class="tree-node-name" slot-scope="{ node, data }">
                      <i :class="data.isdir === 'Y' ? 'el-icon-folder' : 'el-icon-document'" class="node-icon"></i>
                      {{ node.label }}
                    </span>
                  </el-tree>
                </div>
              </div>
            </el-col>

            <!-- 右侧已挂载技术指标表格 -->
            <el-col :span="16" class="table-container">
              <div class="panel-container">
                <div class="panel-header">已挂载技术指标</div>
                <div class="panel-body">
                  <el-table
                    :data="structIndList"
                    border
                    style="width: 100%"
                    v-loading="indTableLoading"
                    height="calc(100% - 20px)">
                    <el-table-column prop="name" label="技术指标名称" min-width="200" show-overflow-tooltip></el-table-column>
                    <el-table-column label="指标类型" width="100">
                      <template slot-scope="scope">
                        <template v-if="scope.row.type === 'text'">
                          <el-tag type="success" size="mini">文本</el-tag>
                        </template>
                        <template v-else-if="scope.row.type === 'num'">
                          <el-tag type="primary" size="mini">数字</el-tag>
                        </template>
                        <template v-else-if="scope.row.type === 'range'">
                          <el-tag type="warning" size="mini">范围</el-tag>
                        </template>
                        <template v-else-if="scope.row.type === 'option'">
                          <el-tag type="info" size="mini">选项</el-tag>
                        </template>
                        <template v-else>
                          <span>-</span>
                        </template>
                      </template>
                    </el-table-column>
                    <el-table-column label="指标值" min-width="150" show-overflow-tooltip>
                      <template slot-scope="scope">
                        <template v-if="scope.row.type === 'text' || scope.row.type === 'num'">
                          <el-tooltip placement="top"
                                     :content="scope.row.values && scope.row.values[0] ? scope.row.values[0].value : '暂无内容'"
                                     :disabled="!scope.row.values || !scope.row.values[0]"
                                     popper-class="content-tooltip">
                            <div class="value-wrapper">
                              <span class="text-value">{{ scope.row.values && scope.row.values[0] ? scope.row.values[0].value : '-' }}</span>
                            </div>
                          </el-tooltip>
                        </template>
                        <template v-else-if="scope.row.type === 'option'">
                          <el-tooltip placement="top"
                                     :content="getOptionsTooltip(scope.row)"
                                     :disabled="!scope.row.values || scope.row.values.length === 0"
                                     popper-class="content-tooltip">
                            <div class="value-wrapper">
                              <span class="count-value">
                                <i class="el-icon-collection-tag"></i> {{ getOptionsCount(scope.row) }}个选项
                              </span>
                            </div>
                          </el-tooltip>
                        </template>
                        <template v-else>
                          <span class="empty-value">-</span>
                        </template>
                      </template>
                    </el-table-column>
                    <el-table-column label="风险状态" width="100" align="center">
                      <template slot-scope="scope">
                        <template v-if="scope.row.riskLevel">
                          <el-tag v-if="scope.row.riskLevel === 'high'" type="danger" size="mini">高风险</el-tag>
                          <el-tag v-else-if="scope.row.riskLevel === 'medium'" type="warning" size="mini">中风险</el-tag>
                          <el-tag v-else-if="scope.row.riskLevel === 'low'" type="info" size="mini">低风险</el-tag>
                          <el-tag v-else-if="scope.row.riskLevel === 'safe'" type="success" size="mini">符合标准</el-tag>
                        </template>
                        <span v-else>-</span>
                      </template>
                    </el-table-column>
                    <el-table-column label="标准状态" width="100" align="center">
                      <template slot-scope="scope">
                        <template v-if="scope.row.existsInStandard !== undefined">
                          <el-tag v-if="scope.row.existsInStandard" type="success" size="mini">标准指标</el-tag>
                          <el-tag v-else type="danger" size="mini">非标指标</el-tag>
                        </template>
                        <span v-else>-</span>
                      </template>
                    </el-table-column>
                    <el-table-column label="操作" width="150" align="center" fixed="right" class-name="operation-column">
                      <template slot-scope="scope">
                        <!-- 修改条件，允许text、option和range类型显示编辑按钮 -->
                        <el-button
                          v-if="scope.row.type === 'text' || scope.row.type === 'option' || scope.row.type === 'range'"
                          size="mini"
                          type="text"
                          icon="el-icon-edit"
                          class="edit-text-btn"
                          @click="handleEditInd(scope.row)">编辑</el-button>
                        <el-button
                          size="mini"
                          type="text"
                          icon="el-icon-delete"
                          class="delete-text-btn"
                          @click="handleRemoveInd(scope.row)">移除</el-button>
                      </template>
                    </el-table-column>
                  </el-table>
                </div>
              </div>
            </el-col>
          </el-row>
        </div>

        <!-- 添加风险评估报告区域 -->
        <div v-if="riskAssessment" class="risk-assessment">
          <div class="risk-header">
            <span class="risk-title">风险评估报告</span>
            <el-button type="text" icon="el-icon-printer" @click="printRiskAssessment">打印报告</el-button>
          </div>
          <div class="risk-content">
            <div class="risk-summary">
              <div class="summary-item">
                <span class="summary-label">检查时间:</span>
                <span class="summary-value">{{ riskAssessment.checkTime }}</span>
              </div>
              <div class="summary-item">
                <span class="summary-label">应用标准:</span>
                <span class="summary-value">{{ getStandardLabel(riskAssessment.standard) }}</span>
              </div>
              <div class="summary-item">
                <span class="summary-label">组成成分:</span>
                <span class="summary-value">{{ riskAssessment.componentName }}</span>
              </div>
              <div class="summary-item">
                <span class="summary-label">检测结果:</span>
                <span class="summary-value" :class="'result-' + riskAssessment.overallRisk">
                  {{ getRiskLevelText(riskAssessment.overallRisk) }}
                </span>
              </div>
            </div>

            <el-divider content-position="center">详细分析</el-divider>

            <div class="risk-details">
              <div v-for="(item, index) in riskAssessment.details" :key="index" class="risk-item" :class="'risk-level-' + item.riskLevel">
                <div class="risk-item-header">
                  <span class="risk-indicator-name">{{ item.name }}</span>
                  <div class="risk-tags">
                    <el-tag size="mini" :type="item.existsInStandard ? 'success' : 'danger'" style="margin-right: 5px">
                      {{ item.existsInStandard ? '标准指标' : '非标指标' }}
                    </el-tag>
                    <el-tag size="mini" :type="getRiskTagType(item.riskLevel)">
                      {{ getRiskLevelText(item.riskLevel) }}
                    </el-tag>
                  </div>
                </div>
                <div class="risk-item-standard" v-if="item.standardRequirement">
                  <span class="standard-label">标准内容:</span>
                  <span class="standard-content">{{ item.standardRequirement }}</span>
                </div>
                <div class="risk-analysis">{{ item.analysis }}</div>
              </div>
            </div>

            <el-divider content-position="center">建议与措施</el-divider>

            <div class="risk-suggestions" v-if="riskAssessment.suggestions && riskAssessment.suggestions.length">
              <div v-for="(suggestion, index) in riskAssessment.suggestions" :key="'sug-'+index" class="suggestion-item">
                <div class="suggestion-number">{{ index + 1 }}</div>
                <div class="suggestion-content">{{ suggestion }}</div>
              </div>
            </div>
            <div v-else class="no-suggestions">
              无特别建议，当前指标符合标准要求。
            </div>
          </div>
        </div>

        <div slot="footer" class="dialog-footer">
          <el-button @click="mountIndOpen = false" class="dialog-btn cancel-btn">取 消</el-button>
          <el-button type="primary" @click="confirmMountInd" class="dialog-btn submit-btn">确 定</el-button>
        </div>
      </div>
    </el-dialog>

    <!-- 编辑文本对话框 -->
    <el-dialog title="编辑文本值" :visible.sync="editTextDialogVisible" width="400px">
      <el-form ref="textForm" :model="textForm" :rules="textRules">
        <el-form-item prop="text">
          <el-input
            type="textarea"
            v-model="textForm.text"
            placeholder="请输入文本值"
            rows="5">
          </el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="editTextDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="confirmEditText">确定</el-button>
      </div>
    </el-dialog>

    <!-- 编辑选项对话框 -->
    <el-dialog title="编辑选项列表" :visible.sync="editOptionsDialogVisible" width="400px">
      <el-form ref="optionsForm">
        <div v-for="(option, index) in currentEditOptions" :key="index" class="option-edit-item">
          <el-input v-model="currentEditOptions[index]" placeholder="请输入选项内容" class="option-input">
            <template slot="prepend">
              <span class="option-index">{{ index + 1 }}.</span>
            </template>
            <template slot="append">
              <el-button @click="removeOption(index)" icon="el-icon-delete" v-if="currentEditOptions.length > 1" class="remove-option-btn"></el-button>
            </template>
          </el-input>
        </div>
      </el-form>
      <div class="option-actions">
        <el-button type="primary" plain size="small" @click="addOption" icon="el-icon-plus" class="add-option-btn">添加选项</el-button>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="editOptionsDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="confirmEditOptions">确定</el-button>
      </div>
    </el-dialog>

    <!-- 修改范围编辑对话框 -->
    <el-dialog title="编辑范围值列表" :visible.sync="editRangeDialogVisible" width="500px">
      <el-form ref="rangeForm">
        <div v-for="(range, index) in currentEditRanges" :key="index" class="range-edit-item">
          <el-row :gutter="10" class="range-input-row">
            <el-col :span="10">
              <el-input
                v-model="range.min"
                placeholder="最小值"
                :min="0"
                :max="range.max - 1"
                class="range-number-input">
              </el-input>
            </el-col>
            <el-col :span="10">
              <el-input
                v-model="range.max"
                placeholder="最大值"
                :min="range.min + 1"
                class="range-number-input">
              </el-input>
            </el-col>
            <el-col :span="4">
              <el-button
                @click="removeRange(index)"
                icon="el-icon-delete"
                v-if="currentEditRanges.length > 1"
                class="remove-range-btn">
              </el-button>
            </el-col>
          </el-row>
        </div>
      </el-form>
      <div class="range-actions">
        <el-button type="primary" plain size="small" @click="addRange" icon="el-icon-plus" class="add-range-btn">
          添加范围
        </el-button>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="editRangeDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="confirmEditRange">确定</el-button>
      </div>
    </el-dialog>

    <!-- 自定义标准内容查看对话框 -->
    <el-dialog title="自定义企业标准内容" :visible.sync="customStandardDialogVisible" width="70%" append-to-body>
      <div class="standard-content-container">
        <el-input
          type="textarea"
          v-model="customStandardContent"
          :rows="20"
          readonly
          resize="none"
          class="standard-content-viewer">
        </el-input>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="customStandardDialogVisible = false">关闭</el-button>
      </div>
    </el-dialog>

    <!-- 提取需求对话框 -->
    <el-dialog title="从非结构性需求提取" :visible.sync="extractDialogVisible" width="70%" append-to-body class="extract-dialog">
      <div class="dialog-container">
        <!-- 添加选项卡切换 -->
        <el-tabs v-model="activeTab">
          <el-tab-pane label="上传文件" name="upload">
            <div class="upload-container">
              <el-upload
                class="upload-demo"
                drag
                action="#"
                :auto-upload="false"
                :on-change="handleFileChange"
                :file-list="fileList"
                :limit="1"
                :on-exceed="handleExceed"
                accept=".txt">
                <i class="el-icon-upload"></i>
                <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
                <div class="el-upload__tip" slot="tip">
                  只能上传TXT文本文件，且不超过10MB。系统将使用大模型提取其中的需求内容。
                </div>
              </el-upload>

              <!-- 添加文件内容预览区域 -->
              <div v-if="fileContent" class="file-preview">
                <div class="preview-header">
                  <span>文件内容预览</span>
                  <span class="preview-info">{{ selectedFile ? selectedFile.name : '' }}</span>
                </div>
                <el-input
                  type="textarea"
                  v-model="fileContent"
                  :rows="10"
                  readonly
                  resize="none"
                  class="preview-content">
                </el-input>
              </div>
            </div>
          </el-tab-pane>

          <el-tab-pane label="直接输入文本" name="text">
            <div class="text-input-container">
              <el-input
                type="textarea"
                v-model="directTextInput"
                :rows="12"
                placeholder="请输入或粘贴文本内容，例如从Word或PDF中复制的文本"
                resize="none">
              </el-input>
              <div class="text-input-tip">
                <p>您可以直接粘贴从Word或PDF中复制的文本，系统将使用大模型分析并提取需求。</p>
                <p>文本长度: {{ directTextInput.length }} 字符</p>
              </div>
            </div>
          </el-tab-pane>
        </el-tabs>

        <!-- 提取结果区域 - 保持不变 -->
        <div v-if="!extractionResults.length && !extracting" class="no-results-tip">
          <el-empty description="尚未提取需求" :image-size="100">
            <template #description>
              <p>{{ activeTab === 'upload' ? '上传文件' : '输入文本' }}后点击"提取需求"按钮，系统将使用大模型分析并提取需求</p>
            </template>
          </el-empty>
        </div>

        <div class="extraction-results" v-if="extractionResults.length > 0">
          <div class="result-header">
            <h3>提取结果 (共 {{extractionResults.length}} 条需求)</h3>
            <div class="result-actions">
              <el-button size="mini" @click="clearResults">清空结果</el-button>
            </div>
          </div>
          <el-divider></el-divider>
          <el-table
            :data="extractionResults"
            style="width: 100%"
            border
            max-height="400">
            <el-table-column prop="name" label="需求名称" min-width="300">
              <template slot-scope="scope">
                <el-input v-model="scope.row.name" placeholder="需求名称"></el-input>
              </template>
            </el-table-column>
            <el-table-column prop="type" label="需求类型" width="200">
              <template slot-scope="scope">
                <el-select v-model="scope.row.type" placeholder="请选择">
                  <el-option label="文本" value="text"></el-option>
                  <el-option label="数值" value="num"></el-option>
                  <el-option label="选项" value="option"></el-option>
                  <el-option label="范围" value="range"></el-option>
                </el-select>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="80" align="center">
              <template slot-scope="scope">
                <el-button
                  size="mini"
                  type="danger"
                  icon="el-icon-delete"
                  @click="removeRequirement(scope.$index)"
                  title="删除该需求">
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="handleCloseExtractDialog">关 闭</el-button>
        <el-button
          type="primary"
          @click="startExtractRequirements"
          :loading="extracting"
          :disabled="(activeTab === 'upload' && !selectedFile) || (activeTab === 'text' && !directTextInput.trim())"
        >提取需求</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  listStruct,
  delStruct,
  addStruct,
  updateStruct,
} from "@/api/data/struct";

import {
  getStructDemandByStructId,
  updateStructDemand,
  delStructDemand,
  addStructDemand,
  removeStructDemand
} from "@/api/data/struct_demand";

import {
  listStructInd,
  getStructInd,
  updateStructInd,
  delStructInd,
  addStructInd,
  getStructIndByStructId,
  removeStructInd
} from "@/api/data/struct_indicator";

import { listDemand, addDemand } from "@/api/data/demand";
import { extractRequirementsFromFile, extractRequirementsFromText, checkNonStandardIndicators } from "@/api/data/llm";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import { listInd } from "../../../api/data/indicator";
import { uploadCustomStandard, getCustomStandardDetails, checkWithCustomStandard } from "@/api/llm";

export default {
  name: "Struct",
  components: { Treeselect },
  data() {
    return {
      // 遮罩层
      loading: true,
      // 显示搜索条件
      showSearch: true,
      // 高速列车结构表格数据
      structList: [],
      // 高速列车结构树选项
      structOptions: [],
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      // 是否展开，默认全部展开
      isExpandAll: true,
      // 重新渲染表格状态
      refreshTable: true,
      // 查询参数
      queryParams: {
        cond: null,
        orderByColumn: 'tseq',
        isAsc: 'desc'
      },
      // 表单参数
      form: {
        id: undefined,
        pid: 0,
        code: '',
        name: '',
        isdir: 'N',
        tseq: 1,
        remark: '',
        text: '',
        options: ''
      },
      // 表单校验
      rules: {
        // 编码验证
        code: [
          { required: true, message: "编码不能为空", trigger: "blur" },
          { max: 50, message: "编码长度不能超过50个字符", trigger: "blur" }
        ],

        // 名称验证
        name: [
          { required: true, message: "名称不能为空", trigger: "blur" },
          { max: 100, message: "名称长度不能超过100个字符", trigger: "blur" }
        ],

        // 文本值验证
        text: [
          { required: true, message: "文本值不能为空", trigger: "blur" }
        ],

        // 选项内容验证
        options: [
          { required: true, message: "选项内容不能为空", trigger: "blur" }
        ]
      },
      // 挂载需求对话框
      mountDemandOpen: false,
      // 正在挂载需求的当前节点
      currentMountNode: null,
      // 需求树数据
      demandTree: [],
      indTree: [],
      // 需求树过滤文本
      filterDemandText: "",
      filterIndText: "",
      // 需求默认属性
      defaultProps: {
        children: "children",
        label: "name"
      },
      // 当前选中的需求节点
      currentDemandNode: null,
      currentIndNode: null,
      // 已挂载的需求列表
      mountedDemands: [],
      mountedInds: [],
      // 已挂载的需求列表(联表查询结果)
      structDemandList: [],
      structIndList: [],
      // 需求加载状态
      demandLoading: false,
      indLoading: false,
      editTextDialogVisible: false, // 控制编辑文本对话框的显示
      editOptionsDialogVisible: false, // 控制编辑选项对话框的显示
      currentEditText: '', // 存储当前编辑的文本
      currentEditOptions: [], // 存储当前编辑的选项列表
      // 主表格遮罩层
      loading: true,
      // 需求树加载状态
      demandTreeLoading: false,
      indTreeLoading: false,
      // 需求表格加载状态
      demandTableLoading: false,
      indTableLoading: false,
      textForm: {
        text: ''
      },
      textRules: {
        text: [
          { required: true, message: "文本值不能为空", trigger: "blur" }
        ]
      },
      // 挂载技术指标对话框
      mountIndOpen: false,
      // 技术指标树数据
      indTree: [],
      // 技术指标树过滤文本
      filterIndText: "",
      // 当前选中的技术指标节点
      currentIndNode: null,
      // 已挂载的技术指标列表
      mountedInds: [],
      // 已挂载的技术指标列表(联表查询结果)
      structIndList: [],
      // 技术指标加载状态
      indLoading: false,
      // 技术指标树加载状态
      indTreeLoading: false,
      // 技术指标表格加载状态
      indTableLoading: false,
      // 当前编辑的值
      currentEditValue: '',
      currentEditId: null,
      // 编辑范围对话框
      editRangeDialogVisible: false,
      currentEditRanges: [], // 新增：当前编辑的范围列表
      extractDialogVisible: false,
      fileList: [],
      selectedFile: null,
      fileContent: '', // 添加文件内容
      extractionResults: [],
      extracting: false,
      activeTab: 'upload', // 默认选中上传文件选项卡
      directTextInput: '', // 用户直接输入的文本
      selectedStandard: null,
      standardOptions: [
          {
            "value": "TB/T-3139",
            "label": "TB/T 3139-2021 机车车辆非金属材料及室内空气有害物质限量"
          },
          {
            "value": "TB/T-3491",
            "label": "TB/T 3491-2017 电动车组司机室设计规范"
          },
          {
            "value": "TB/T-3549.2",
            "label": "TB/T 3549.2-2021 机车车辆强度设计及试验鉴定规范 转向架 第2部分：三大件式转向架"
          },
          {
            "value": "TB/T-3550.1",
            "label": "TB/T 3550.1-2019 机车车辆强度设计及试验鉴定规范 车体 第1部分：客车车体"
          },
          {
            "value": "TB/T-3402",
            "label": "TB/T 3402-2015 动车组制动系统"
          },
          {
            "value": "TB/T-3403",
            "label": "TB/T 3403-2015 动车组制动控制系统"
          },
          {
            "value": "TB/T-3404",
            "label": "TB/T 3404-2015 动车组制动装置零部件设计和制造要求及装车后的试验方法"
          },
          {
            "value": "ISO-22100",
            "label": "ISO 22100:2016 铁路设施 - 机车车辆安全"
          },
          {
            "value": "EN-50126",
            "label": "EN 50126 铁路应用 - 可靠性、可用性、可维护性与安全性 (RAMS) 规范"
          },
          {
            "value": "EN-50129",
            "label": "EN 50129 铁路应用 - 通信、信号和处理系统 - 安全相关电子系统"
          },
          {
            "value": "EN-15227",
            "label": "EN 15227 铁路车辆防火、防爆要求"
          },
          {
            "value": "DIN-5510",
            "label": "DIN 5510 铁路车辆防火和阻燃要求"
          },
          {
            "value": "ISO-16890",
            "label": "ISO 16890:2016 空气过滤器"
          },
          {
            "value": "EN-13779",
            "label": "EN 13779:2007 通风系统用空气净化装置"
          },
        ],
      checkingIndicators: false,
      riskAssessment: null,
      customStandard: null,
      hasValidStandard: false,
      customStandardDialogVisible: false,
      customStandardContent: '',
    };
  },
  created() {
    this.getList();
  },
  methods: {
    /** 查询高速列车结构列表 */
    getList() {
      this.loading = true;
      listStruct(this.queryParams).then(response => {
        this.structList = this.handleTree(response.data, "id", "pid");
        this.loading = false;
        this.$refs.cond.focus();
      });
    },
    /** 转换高速列车结构数据结构 */
    normalizer(node) {
      if (node.children && !node.children.length) {
        delete node.children;
      }
      return {
        id: node.id,
        label: node.name,
        children: node.children
      };
    },
    /** 行样式 */
    rowClassName({row, rowIndex}) {
      let classes = 'tree-row';
      if (row.isdir === 'Y') {
        classes += ' parent-node';
      }
      return classes;
    },
    /** 查询高速列车结构下拉树结构 */
    getTreeselect() {
      listStruct().then(res => {
        this.structOptions = [];
        const data = { id: "0", name: "顶级节点", children: [] };

        // 过滤掉非目录节点，只保留 isdir='Y' 的节点
        const filteredData = res.data.filter(item => item.isdir === 'Y');

        data.children = this.handleTree(filteredData, "id", "pid");
        this.structOptions.push(data);
      });
    },
    // 取消按钮
    cancel() {
      this.open = false;
      this.resetForm();
    },
    // 表单重置
    resetForm() {
      this.form = {
        id: undefined,
        pid: 0,
        code: '',
        name: '',
        isdir: 'N',
        tseq: 1,
        remark: '',
        text: '',
        options: ''
      };
      if (this.$refs.form) {
        this.$refs.form.resetFields();
      }
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm();
      this.handleQuery();
    },
    /** 新增按钮操作 */
    handleAdd(row) {
      this.resetForm();
      this.getTreeselect();
      if (row != null && row.id) {
        this.form.pid = row.id;
      } else {
        this.form.pid = 0;
      }
      this.open = true;
      this.title = "添加高速列车结构";
      this.$nextTick(() => {
        this.$refs.code.focus();
      });
    },
    /** 展开/折叠操作 */
    toggleExpandAll() {
      this.refreshTable = false;
      this.isExpandAll = !this.isExpandAll;
      this.$nextTick(() => {
        this.refreshTable = true;
      });
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.resetForm();
      this.getTreeselect();
      if (row != null) {
        this.form = { ...row };
      }
      this.open = true;
      this.title = "修改高速列车结构";
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          if (this.form.id != null) {
            updateStruct(this.form).then(response => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            addStruct(this.form).then(response => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        } else {
          this.$message.error("请填写所有必填项");
        }
      });
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      this.$modal.confirm('是否确认删除高速列车结构编号为"' + row.id + '"的数据项？').then(function() {
        return delStruct(row.id);
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {});
    },
    /** 挂载需求 */
    handleMountDemand(row) {
      this.currentMountNode = row;
      this.mountDemandOpen = true;
      // 同时加载两侧数据，使用不同的loading状态
      this.getMountedDemands(row.id);
      this.getDemandData();
    },
    /** 获取已挂载的需求数据 */
    getMountedDemands(structId) {
      this.demandTableLoading = true;
      getStructDemandByStructId(structId).then(async response => {
        let structDemands = response.data || [];

        if (structDemands.length > 0) {
          try {
            const demandResponse = await listDemand();
            const demandMap = {};
            demandResponse.data.forEach(demand => {
              demandMap[demand.id] = demand;
            });

            // 按需求分组处理值
            const groupedDemands = {};
            structDemands.forEach(item => {
              const demandDetail = demandMap[item.did] || {};
              const key = item.did;

              if (!groupedDemands[key]) {
                groupedDemands[key] = {
                  ...item,
                  name: demandDetail.name || '未知需求',
                  type: demandDetail.type || 'text',
                  values: []
                };
              }

              if (item.value) {
                groupedDemands[key].values.push({
                  id: item.id,
                  value: item.value
                });
              }
            });

            structDemands = Object.values(groupedDemands);
          } catch (error) {
            console.error("获取需求详情失败:", error);
          }
        }

        this.structDemandList = structDemands;
        this.mountedDemands = structDemands;
        this.demandTableLoading = false;
      }).catch(error => {
        console.error("获取已挂载需求失败:", error);
        this.$message.error("获取已挂载需求失败");
        this.demandTableLoading = false;
      });
    },
    /** 获取需求数据 */
    getDemandData() {
      this.demandTreeLoading = true; // 使用专门的树loading状态
      // 调用后端API获取需求数据
      listDemand().then(response => {
        // 将后端返回的数据转换为树状结构
        this.demandTree = this.handleTree(response.data, "id", "pid");
        this.demandTreeLoading = false; // 完成加载
      }).catch(error => {
        console.error("获取需求数据失败:", error);
        this.$message.error("获取需求数据失败");
        this.demandTreeLoading = false; // 出错时也要关闭loading
      });
    },
    /** 处理需求节点点击 */
    handleDemandNodeClick(data) {
      console.log('节点数据:', data); // 检查节点数据
      if (data.isdir !== 'Y') {
        const demandId = data.id; // 使用正确的字段
        console.log('需求ID:', demandId);

        // 检查是否已经挂载
        const isAlreadyMounted = this.mountedDemands.some(item => item.did === demandId);

        if (!isAlreadyMounted) {
          // 创建新的需求挂载关系
          const demandData = {
            sid: this.currentMountNode.id,
            did: demandId, // 使用需求ID
            type: data.type || 'text'
          };

          // 调用后端API挂载需求
          this.demandLoading = true;
          addStructDemand(demandData).then(() => {
            this.$message.success('需求挂载成功');
            // 刷新已挂载需求列表
            this.getMountedDemands(this.currentMountNode.id);
          }).catch(error => {
            console.error("需求挂载失败:", error);
            this.$message.error("需求挂载失败");
            this.demandLoading = false;
          });
        } else {
          this.$message.warning('该需求已挂载');
        }
      }
    },
    /** 处理编辑范围 */
    handleEditDemand(row) {
      this.currentDemandNode = row;

      if (row.type === 'range') {
        // 初始化范围列表
        this.currentEditRanges = row.values ? row.values.map(v => {
          const [min, max] = v.value.split('-').map(Number);
          return { min, max };
        }) : [{ min: 0, max: 100 }];
        this.editRangeDialogVisible = true;
      } else if (row.type === 'text') {
        // 文本类型直接编辑value
        this.textForm.text = row.values && row.values[0] ? row.values[0].value : '';
        this.editTextDialogVisible = true;
      } else if (row.type === 'option') {
        // 选项类型显示所有values
        this.currentEditOptions = row.values ? row.values.map(v => v.value) : [];
        this.editOptionsDialogVisible = true;
      }
    },
    /** 添加新范围 */
    addRange() {
      this.currentEditRanges.push({ min: 0, max: 100 });
    },
    /** 移除范围 */
    removeRange(index) {
      this.currentEditRanges.splice(index, 1);
    },
    /** 确认编辑范围 */
    confirmEditRange() {
      // 验证范围值的有效性
      const hasInvalidRange = this.currentEditRanges.some(range =>
        range.min === undefined ||
        range.max === undefined ||
        range.min >= range.max
      );

      if (hasInvalidRange) {
        this.$message.error("请输入有效的范围值");
        return;
      }

      // 检查范围重叠
      const sortedRanges = [...this.currentEditRanges].sort((a, b) => a.min - b.min);
      for (let i = 0; i < sortedRanges.length - 1; i++) {
        if (sortedRanges[i].max > sortedRanges[i + 1].min) {
          this.$message.error("范围区间不能重叠");
          return;
        }
      }

      // 检查重复范围
      const rangeStrings = this.currentEditRanges.map(range => `${range.min}-${range.max}`);
      if (new Set(rangeStrings).size !== rangeStrings.length) {
        this.$message.error("不能添加重复的范围");
        return;
      }

      if (this.currentDemandNode) {
        // 删除旧的范围记录
        const oldValues = this.currentDemandNode.values || [];
        const deletePromises = oldValues.map(v =>
          delStructDemand(v.id)
        );

        // 添加新的范围记录
        Promise.all(deletePromises)
          .then(() => {
            const addPromises = this.currentEditRanges.map(range => {
              const newData = {
                sid: this.currentMountNode.id,
                did: this.currentDemandNode.did,
                value: `${range.min}-${range.max}`
              };
              return addStructDemand(newData);
            });
            return Promise.all(addPromises);
          })
          .then(() => {
            this.$message.success('更新需求范围成功');
            this.editRangeDialogVisible = false;
            this.getMountedDemands(this.currentMountNode.id);
          })
          .catch(error => {
            console.error("更新需求范围失败:", error);
            this.$message.error("更新需求范围失败");
          });
      }
    },
    /** 编辑文本 */
    confirmEditText() {
      this.$refs.textForm.validate((valid) => {
        if (valid) {
          if (this.currentDemandNode) {
            // 更新需求文本
            const updateData = {
              id: this.currentDemandNode.id,
              sid: this.currentMountNode.id,
              did: this.currentDemandNode.did,
              value: this.textForm.text
            };

            updateStructDemand(updateData).then(() => {
              this.$message.success('更新需求成功');
              this.editTextDialogVisible = false;
              this.getMountedDemands(this.currentMountNode.id);
            }).catch(error => {
              console.error("更新需求失败:", error);
              this.$message.error("更新需求失败");
            });
          } else if (this.currentIndNode) {
            // 更新技术指标文本
            const updateData = {
              id: this.currentIndNode.id,
              sid: this.currentMountNode.id,
              iid: this.currentIndNode.iid,
              value: this.textForm.text
            };

            updateStructInd(updateData).then(() => {
              this.$message.success('更新技术指标成功');
              this.editTextDialogVisible = false;
              this.getMountedInds(this.currentMountNode.id);
            }).catch(error => {
              console.error("更新技术指标失败:", error);
              this.$message.error("更新技术指标失败");
            });
          }
        }
      });
    },
    /** 确认编辑选项 */
    confirmEditOptions() {
      // 验证选项不为空
      const hasEmptyOption = this.currentEditOptions.some(option => !option.trim());
      if (hasEmptyOption || this.currentEditOptions.length === 0) {
        this.$message.error("选项内容不能为空");
        return;
      }

      if (this.currentDemandNode) {
        // 删除旧的选项记录，使用 del 删除单个选项记录
        const oldValues = this.currentDemandNode.values || [];
        const deletePromises = oldValues.map(v =>
          delStructDemand(v.id)
        );

        // 添加新的选项记录
        Promise.all(deletePromises)
          .then(() => {
            const addPromises = this.currentEditOptions.map(option => {
              const newData = {
                sid: this.currentMountNode.id,
                did: this.currentDemandNode.did,
                value: option
              };
              return addStructDemand(newData);
            });
            return Promise.all(addPromises);
          })
          .then(() => {
            this.$message.success('更新需求选项成功');
            this.editOptionsDialogVisible = false;
            this.getMountedDemands(this.currentMountNode.id);
          })
          .catch(error => {
            console.error("更新需求选项失败:", error);
            this.$message.error("更新需求选项失败");
          });
      } else if (this.currentIndNode) {
        // 删除旧的选项记录，使用 del 删除单个选项记录
        const oldValues = this.currentIndNode.values || [];
        const deletePromises = oldValues.map(v =>
          delStructInd(v.id)
        );

        // 添加新的选项记录
        Promise.all(deletePromises)
          .then(() => {
            const addPromises = this.currentEditOptions.map(option => {
              const newData = {
                sid: this.currentMountNode.id,
                iid: this.currentIndNode.iid,
                value: option
              };
              return addStructInd(newData);
            });
            return Promise.all(addPromises);
          })
          .then(() => {
            this.$message.success('更新技术指标选项成功');
            this.editOptionsDialogVisible = false;
            this.getMountedInds(this.currentMountNode.id);
          })
          .catch(error => {
            console.error("更新技术指标选项失败:", error);
            this.$message.error("更新技术指标选项失败");
          });
      }
    },
    /** 添加选项 */
    addOption() {
      this.currentEditOptions.push('');
    },
    /** 移除选项 */
    removeOption(index) {
      this.currentEditOptions.splice(index, 1);
    },
    /** 过滤需求树节点 */
    filterDemandNode(value, data) {
      if (!value) return true;
      return data.name && data.name.indexOf(value) !== -1;
    },
    /** 过滤需求树节点(输入框变化时触发) */
    filterDemandTreeNodes() {
      if (this.$refs.demandTree) {
        this.$refs.demandTree.filter(this.filterDemandText);
      }
    },
    /** 确认挂载需求 */
    confirmMountDemand() {
      // 关闭对话框并刷新主列表
      this.mountDemandOpen = false;
      this.getList();
    },
    /** 获取选项数量 */
    getOptionsCount(row) {
      return row.values ? row.values.length : 0;
    },
    /** 获取选项提示内容 */
    getOptionsTooltip(row) {
      if (!row.values || row.values.length === 0) {
        return "暂无选项";
      }

      return row.values
        .map((v, index) => `${index + 1}. ${v.value.trim()}`)
        .join('\n');
    },
    /** 移除需求 */
    handleRemoveDemand(row) {
      this.$modal.confirm('确定要移除该需求吗？').then(() => {
        // 使用 remove 移除整个需求关联
        removeStructDemand(row.did).then(() => {
          this.$message.success('移除需求成功');
          this.getMountedDemands(this.currentMountNode.id);
        }).catch(error => {
          console.error("移除需求失败:", error);
          this.$message.error("移除需求失败");
        });
      }).catch(() => {
        console.log("取消移除操作");
      });
    },
    /** 挂载技术指标 */
    handleMountTechnical(row) {
      this.currentMountNode = row;
      this.mountIndOpen = true;
      // 同时加载两侧数据，使用不同的loading状态
      this.getMountedInds(row.id);
      this.getIndData();
    },
    /** 获取已挂载的技术指标数据 */
    getMountedInds(structId) {
      this.indTableLoading = true;
      getStructIndByStructId(structId).then(async response => {
        let structInds = response.data || [];

        if (structInds.length > 0) {
          try {
            const indResponse = await listInd();
            const indMap = {};
            indResponse.data.forEach(ind => {
              indMap[ind.id] = ind;
            });

            // 按技术指标分组处理值
            const groupedInds = {};
            structInds.forEach(item => {
              const indDetail = indMap[item.iid] || {};
              const key = item.iid;

              if (!groupedInds[key]) {
                groupedInds[key] = {
                  ...item,
                  name: indDetail.name || '未知技术指标',
                  type: indDetail.type || 'text',
                  values: []
                };
              }

              if (item.value) {
                groupedInds[key].values.push({
                  id: item.id,
                  value: item.value
                });
              }
            });

            structInds = Object.values(groupedInds);
          } catch (error) {
            console.error("获取技术指标详情失败:", error);
          }
        }

        this.structIndList = structInds;
        this.mountedInds = structInds;
        this.indTableLoading = false;
      }).catch(error => {
        console.error("获取已挂载技术指标失败:", error);
        this.$message.error("获取已挂载技术指标失败");
        this.indTableLoading = false;
      });
    },
    /** 获取技术指标数据 */
    getIndData() {
      this.indTreeLoading = true;
      // 调用后端API获取技术指标数据
      listInd().then(response => {
        // 将后端返回的数据转换为树状结构
        this.indTree = this.handleTree(response.data, "id", "pid");
        this.indTreeLoading = false;
      }).catch(error => {
        console.error("获取技术指标数据失败:", error);
        this.$message.error("获取技术指标数据失败");
        this.indTreeLoading = false;
      });
    },
    /** 处理技术指标节点点击 */
    handleIndNodeClick(data) {
      console.log('节点数据:', data);
      if (data.isdir !== 'Y') {
        const indId = data.id;
        console.log('技术指标ID:', indId);

        const isAlreadyMounted = this.mountedInds.some(item => item.iid === indId);

        if (!isAlreadyMounted) {
          const indData = {
            sid: this.currentMountNode.id,
            iid: indId,
            type: data.type || 'text'
          };

          this.indLoading = true;
          addStructInd(indData).then(() => {
            this.$message.success('技术指标挂载成功');
            this.getMountedInds(this.currentMountNode.id);
          }).catch(error => {
            console.error("技术指标挂载失败:", error);
            this.$message.error("技术指标挂载失败");
            this.indLoading = false;
          });
        } else {
          this.$message.warning('该技术指标已挂载');
        }
      }
    },
    /** 编辑技术指标 */
    handleEditInd(row) {
      this.currentIndNode = row;
      this.currentDemandNode = null;

      if (row.type === 'text') {
        this.textForm.text = row.values && row.values[0] ? row.values[0].value : '';
        this.editTextDialogVisible = true;
      } else if (row.type === 'option') {
        this.currentEditOptions = row.values ? row.values.map(v => v.value) : [];
        this.editOptionsDialogVisible = true;
      }
    },
    /** 移除技术指标 */
    handleRemoveInd(row) {
      this.$modal.confirm('确定要移除该技术指标吗？').then(() => {
        // 使用 remove 移除整个技术指标关联
        removeStructInd(row.iid).then(() => {
          this.$message.success('移除技术指标成功');
          this.getMountedInds(this.currentMountNode.id);
        }).catch(error => {
          console.error("移除技术指标失败:", error);
          this.$message.error("移除技术指标失败");
        });
      }).catch(() => {
        console.log("取消移除操作");
      });
    },
    /** 获取范围数量 */
    getRangeCount(row) {
      return row.values ? row.values.length : 0;
    },

    /** 获取范围提示内容 */
    getRangeTooltip(row) {
      if (!row.values || row.values.length === 0) return '';
      return row.values.map(v => v.value.replace('-', ' - ')).join('\n');
    },

    // 修改或添加：确保关闭挂载需求对话框时执行正确的清理
    handleCloseMountDemand() {
      this.mountDemandOpen = false;
      this.currentDemandNode = null;
      this.filterDemandText = "";
      // 可能需要其他清理步骤
    },

    // 修改或添加：确保关闭挂载技术指标对话框时执行正确的清理
    handleCloseMountInd() {
      this.mountIndOpen = false;
      this.currentIndNode = null;
      this.filterIndText = "";
      // 可能需要其他清理步骤
    },
    openExtractRequirementsDialog() {
      this.extractDialogVisible = true;
      this.extractionResults = [];
      this.fileList = [];
      // 确保重置上传文件状态
      this.selectedFile = null;
      this.fileContent = "";
      this.extracting = false;
      this.getTreeselect(); // 加载结构树数据
    },

    // 关闭对话框时重置状态
    handleCloseExtractDialog() {
      this.extractDialogVisible = false;
      this.extractionResults = [];
      this.fileList = [];
      this.selectedFile = null;
      this.fileContent = "";
      this.extracting = false;
      this.activeTab = 'upload';
    },
    // 处理文件选择变化
    handleFileChange(file, fileList) {
      // 检查文件类型
      const isTxtFile = file.raw.type === 'text/plain';

      // 检查文件大小
      const isLt10M = file.raw.size / 1024 / 1024 < 10;

      if (!isTxtFile) {
        this.$message.error('只能上传TXT文本文件!');
        this.fileList = [];
        return false;
      }

      if (!isLt10M) {
        this.$message.error('文件大小不能超过 10MB!');
        this.fileList = [];
        return false;
      }

      this.fileList = fileList.slice(-1); // 只保留最后选择的文件
      this.selectedFile = file; // 保存文件对象

      // 读取文件内容
      const reader = new FileReader();
      reader.onload = (e) => {
        try {
          // 尝试自动检测编码并转换
          const buffer = e.target.result;
          // 检查是否有 BOM 标记
          if (buffer.slice(0, 2) === '\uFFFE') {
            // UTF-16 (LE)
            this.fileContent = buffer.slice(2);
          } else if (buffer.slice(0, 2) === '\uFEFF') {
            // UTF-16 (BE)
            this.fileContent = buffer.slice(2);
          } else if (buffer.slice(0, 1) === '\uFEFF') {
            // UTF-8 with BOM
            this.fileContent = buffer.slice(1);
          } else {
            // 没有 BOM，直接使用内容
            this.fileContent = buffer;
          }

          // 如果内容看起来像乱码，尝试使用 TextDecoder 解码
          if (this.seemsLikeGarbage(this.fileContent)) {
            const textDecoder = new TextDecoder('gbk');
            const uint8Array = new Uint8Array(file.raw.size);
            const fileReader = new FileReader();
            fileReader.onload = () => {
              const arrayBuffer = fileReader.result;
              uint8Array.set(new Uint8Array(arrayBuffer));
              this.fileContent = textDecoder.decode(uint8Array);
            };
            fileReader.readAsArrayBuffer(file.raw);
          }
        } catch (error) {
          console.error('文件读取错误:', error);
          this.$message.error('文件内容读取失败，请检查文件编码是否正确');
        }
      };
      reader.onerror = (error) => {
        console.error('文件读取错误:', error);
        this.$message.error('文件读取失败，请重试');
      };
      reader.readAsText(file.raw, 'UTF-8'); // 首先尝试 UTF-8
    },

    // 检查文本是否看起来像乱码
    seemsLikeGarbage(text) {
      if (!text) return false;

      // 计算不可打印字符的比例
      const unprintableCount = text.split('').filter(char => {
        const code = char.charCodeAt(0);
        return code < 32 || code > 126;
      }).length;

      const ratio = unprintableCount / text.length;
      // 如果不可打印字符比例过高，可能是编码问题
      return ratio > 0.3;
    },

    handleExceed(files, fileList) {
      this.$message.warning('只能上传一个文件，请先删除已有文件');
    },

    // 根据当前选择的选项卡启动相应的处理
    startExtractRequirements() {
      if (this.activeTab === 'upload' && this.fileContent) {
        // 如果是文件上传，直接使用文件内容作为文本输入
        this.extractRequirementsFromDirectText(this.fileContent);
      } else if (this.activeTab === 'text' && this.directTextInput.trim()) {
        // 如果是直接输入文本
        this.extractRequirementsFromDirectText(this.directTextInput);
      } else {
        this.$message.warning(this.activeTab === 'upload' ? '请先上传文件' : '请先输入文本内容');
      }
    },

    // 从直接输入的文本中提取需求
    extractRequirementsFromDirectText(text) {
      if (!text) {
        this.$message.warning('请先输入文本内容');
        return;
      }

      this.extracting = true;

      // 显示加载提示
      const loading = this.$loading({
        lock: true,
        text: '正在分析文本内容...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      });

        // 定义计时器，每5秒更新加载消息，提供进度感知
        let processingTimeSeconds = 0;
        const updateTimer = setInterval(() => {
          processingTimeSeconds += 5;
          if (processingTimeSeconds < 60) {
          loading.text = `正在分析文本内容，已处理 ${processingTimeSeconds} 秒...`;
          } else {
            const minutes = Math.floor(processingTimeSeconds / 60);
            const seconds = processingTimeSeconds % 60;
          loading.text = `处理较大文本，已用时 ${minutes} 分 ${seconds} 秒，请耐心等待...`;
          }
        }, 5000);

      // 调用后端API处理文本 - 修改为直接发送文本内容
      extractRequirementsFromText(text)
          .then(response => {
            clearInterval(updateTimer);
            if (response.code === 200 && response.data) {
              this.processExtractionResults(response.data);
              this.$message.success('需求提取成功');
            } else {
              this.$message.error(response.msg || '需求提取失败');
            }
          })
          .catch(error => {
            console.error('提取需求失败:', error);

            // 构建详细的错误消息
          let errorMsg = '从文本提取需求失败';

            if (error.response && error.response.data) {
              if (error.response.data.msg) {
                errorMsg += ': ' + error.response.data.msg;
              } else if (typeof error.response.data === 'string') {
                errorMsg += ': ' + error.response.data;
              }
            } else if (error.message) {
              if (error.message.includes('timeout')) {
              errorMsg = '处理超时，请尝试减少文本内容或分段处理';
              } else {
                errorMsg += ': ' + error.message;
              }
            }

          // 显示错误消息
            this.$message({
              type: 'error',
              dangerouslyUseHTMLString: true,
              message: `<div>
                <p><strong>处理失败</strong></p>
                <p>${errorMsg}</p>
                <p>建议：</p>
                <ul>
                <li>尝试减少文本内容</li>
                <li>尝试分段处理</li>
                <li>检查文本编码是否为UTF-8</li>
                </ul>
              </div>`,
              duration: 10000
            });
          })
          .finally(() => {
            clearInterval(updateTimer);
            this.extracting = false;
            loading.close();
          });
    },

    processExtractionResults(data) {
      if (data && data.length > 0) {
        // 格式化提取结果为需求对象，仍然保留content字段用于保存需求
        this.extractionResults = data.map(item => ({
          name: item.name || '',
          content: item.content || '', // 仍保留content字段，虽然不显示但保存时需要
          type: item.type || 'text',
          isdir: 'N',
          pid: 0 // 默认添加到根目录
        }));

        this.$message.success(`成功提取 ${this.extractionResults.length} 条需求`);
      } else {
        this.$message.warning('未能提取到有效需求');
      }
    },
    saveRequirement(requirement, index) {
      if (!requirement.name) {
        this.$message.warning('需求名称不能为空');
        return;
      }

      // 保存单个需求
      addDemand({
        name: requirement.name,
        type: requirement.type,
        isdir: 'N',
        pid: requirement.pid || 0,
        content: requirement.content
      }).then(response => {
        this.$message.success('需求保存成功');
        // 从结果列表中移除
        this.extractionResults.splice(index, 1);
      }).catch(error => {
        console.error('保存需求失败:', error);
        this.$message.error('保存需求失败');
      });
    },
    saveAllRequirements() {
      if (this.extractionResults.length === 0) {
        this.$message.warning('没有需求可以保存');
        return;
      }

      // 创建一个记录保存进度的变量
      let savedCount = 0;
      const totalCount = this.extractionResults.length;

      // 显示加载提示
      const loading = this.$loading({
        lock: true,
        text: '正在保存需求...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      });

      // 依次保存所有需求
      const savePromises = this.extractionResults.map(requirement => {
        return addDemand({
          name: requirement.name || '未命名需求',
          type: requirement.type || 'text',
          isdir: 'N',
          pid: requirement.pid || 0,
          content: requirement.content || ''
        }).then(() => {
          savedCount++;
          // 更新加载提示文本
          loading.text = `正在保存需求... (${savedCount}/${totalCount})`;
        });
      });

      // 所有需求保存完成后
      Promise.all(savePromises).then(() => {
        loading.close();
        this.$message.success(`成功保存 ${savedCount} 条需求`);
        this.extractionResults = [];
        // 刷新需求列表
        this.getList();
      }).catch(error => {
        loading.close();
        console.error('批量保存需求失败:', error);
        this.$message.error(`已保存 ${savedCount} 条需求，但部分需求保存失败`);
      });
    },
    removeRequirement(index) {
      this.extractionResults.splice(index, 1);
    },
    clearResults() {
      this.$confirm('确定要清空所有提取结果吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.extractionResults = [];
      }).catch(() => {});
    },
    checkNonStandardIndicators() {
      if (this.structIndList.length === 0) {
        this.$message.warning('请先挂载技术指标');
        return;
      }

      if (!this.selectedStandard && !this.customStandard) {
        this.$message.warning('请选择标准或上传企业标准');
        return;
      }

      this.checkingIndicators = true;

      // 准备请求数据
      const requestData = {
        componentName: this.currentMountNode.name,
        indicators: this.structIndList.map(indicator => {
          return {
            id: indicator.iid,
            name: indicator.name,
            type: indicator.type,
            value: indicator.values && indicator.values.length > 0
              ? (indicator.type === 'option'
                ? indicator.values.map(v => v.value)
                : indicator.values[0].value)
              : null
          };
        })
      };

      // 根据标准类型选择不同的接口
      let checkPromise;
      if (this.customStandard) {
        // 使用自定义标准
        requestData.standardId = this.customStandard.id;
        checkPromise = checkWithCustomStandard(requestData);
        } else {
        // 使用预定义标准
        requestData.standardCode = this.selectedStandard;
        checkPromise = checkNonStandardIndicators(requestData);
      }

      // 调用检查API
      checkPromise.then(response => {
          if (response.code === 200 && response.data) {
          this.riskAssessment = response.data;

          // 更新技术指标的风险级别
          if (this.riskAssessment.details && this.riskAssessment.details.length > 0) {
            this.structIndList.forEach(indicator => {
              const riskDetail = this.riskAssessment.details.find(
                detail => detail.name === indicator.name
              );
              if (riskDetail) {
                this.$set(indicator, 'riskLevel', riskDetail.riskLevel);
                this.$set(indicator, 'existsInStandard', riskDetail.existsInStandard);
              }
            });
          }

          this.$message.success('技术指标标准检查完成');
          } else {
          this.$message.error(response.msg || '检查失败');
        }
      }).catch(error => {
        console.error('检查技术指标失败:', error);
        this.$message.error('检查技术指标失败: ' + (error.message || '未知错误'));
      }).finally(() => {
        this.checkingIndicators = false;
      });
    },
    getStandardLabel(standard) {
      if (!standard) return '未选择标准';

      // 如果是自定义标准
      if (this.customStandard && this.customStandard.name === standard) {
        return this.customStandard.name + ' (自定义标准)';
      }

      // 如果是预定义标准
      const found = this.standardOptions.find(option => option.value === standard);
      return found ? found.label : standard;
    },
    getRiskLevelText(riskLevel) {
      const riskLevels = {
        high: '高风险',
        medium: '中风险',
        low: '低风险',
        safe: '符合标准',
      };
      return riskLevels[riskLevel] || riskLevel;
    },
    getRiskTagType(riskLevel) {
      const riskTags = {
        high: 'danger',
        medium: 'warning',
        low: 'info',
        safe: 'success',
      };
      return riskTags[riskLevel] || riskLevel;
    },
    printRiskAssessment() {
      // 这里可以添加打印风险评估报告的逻辑
      console.log('打印风险评估报告');
    },
    handleCustomStandardSuccess(response, file) {
      this.customStandard = {
        id: response.data.id,
        name: file.name,
        size: file.size,
        url: response.data.url
      };
      this.hasValidStandard = true;
      this.$message.success('企业标准上传成功');
    },
    handleCustomStandardError(error) {
      this.$message.error('企业标准上传失败，请重试');
    },
    /**
     * 上传前检查自定义标准文档
     */
    beforeCustomStandardUpload(file) {
      // 验证文件大小
      const isLt10M = file.size / 1024 / 1024 < 10;
      if (!isLt10M) {
        this.$message.error('文件大小不能超过10MB!');
        return false;
      }

      // 验证文件类型 - 仅支持TXT文件
      const isTxtFile = file.type === 'text/plain';
      if (!isTxtFile) {
        this.$message.error('只能上传TXT文本文件!');
        return false;
      }

      return true;
    },

    /**
     * 上传自定义标准文档
     */
    uploadCustomStandard(options) {
      const { file } = options;

      // 提示用户输入标准名称
      this.$prompt('请输入企业标准名称', '上传企业标准', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputPattern: /\S+/,
        inputErrorMessage: '标准名称不能为空'
      }).then(({ value }) => {
        // 显示上传中提示
        const loading = this.$loading({
          lock: true,
          text: '正在读取文件内容...',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)'
        });

        // 读取文件内容
        const reader = new FileReader();
        reader.onload = (e) => {
          const fileContent = e.target.result;

          // 创建请求数据
          const requestData = {
            standardName: value,
            content: fileContent
          };

          // 调用上传API
          uploadCustomStandard(requestData).then(response => {
            loading.close();
            if (response.code === 200) {
              this.$message.success('企业标准文档上传成功');

              // 保存自定义标准信息
              this.customStandard = response.data;
              this.selectedStandard = null; // 清除预定义标准选择
              this.hasValidStandard = true;
            } else {
              this.$message.error(response.msg || '上传失败');
            }
          }).catch(error => {
            loading.close();
            console.error('上传企业标准文档失败:', error);
            this.$message.error('上传企业标准文档失败，请重试');
          });
        };

        reader.onerror = () => {
          loading.close();
          this.$message.error('读取文件内容失败，请重试');
        };

        reader.readAsText(file);
      }).catch(() => {
        // 用户取消输入
      });
    },
    viewCustomStandard() {
      if (!this.customStandard) {
        this.$message.warning('未找到自定义标准');
        return;
      }

      // 显示加载中
      const loading = this.$loading({
        lock: true,
        text: '加载标准内容...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      });

      // 获取标准详情
      getCustomStandardDetails(this.customStandard.id).then(response => {
          loading.close();
        if (response.code === 200) {
          this.customStandardContent = response.data.content || '无法显示内容';
          this.customStandardDialogVisible = true;
        } else {
          this.$message.error(response.msg || '获取标准内容失败');
        }
      }).catch(error => {
        loading.close();
        console.error('获取标准内容失败:', error);
        this.$message.error('获取标准内容失败，请重试');
        });
    },
    removeCustomStandard() {
      this.customStandard = null;
      this.hasValidStandard = this.selectedStandard != null;
      this.$message.success('已移除企业标准');
    },
    formatFileSize(bytes) {
      if (bytes < 1024) {
        return bytes + ' B';
      } else if (bytes < 1048576) {
        return (bytes / 1024).toFixed(2) + ' KB';
      } else {
        return (bytes / 1048576).toFixed(2) + ' MB';
      }
    },
  },
  watch: {
    // 监听标准选择变化
    selectedStandard(val) {
      this.hasValidStandard = val != null || this.customStandard != null;

      // 如果选择了预定义标准，清除自定义标准
      if (val) {
        this.customStandard = null;
      }
    }
  }
};
</script>

<style lang="scss" scoped>
// 整体容器样式优化 - 更加商务化的设计
.app-container {
  background-color: #fafbfc;
  border-radius: 4px;
  padding: 24px;
  box-shadow: 0 1px 8px rgba(0, 0, 0, 0.03);
}

// 搜索区域优化 - 简洁商务风格
::v-deep .el-form {
  background-color: #fff;
  padding: 16px;
  border-radius: 4px;
  margin-bottom: 20px;
  border: 1px solid #ebeef5;

  .el-input__inner {
    border-radius: 3px;
    transition: all 0.2s;
  }

  .el-form-item {
    margin-bottom: 0;
  }
}

// 按钮区域优化 - 更加商务化的布局
.mb8 {
  margin-bottom: 15px;
  display: flex;
  align-items: center;
  background-color: #fff;
  padding: 12px 16px;
  border-radius: 4px;
  border: 1px solid #ebeef5;
}

// 表格样式优化 - 商务风格
.tree-table {
  margin-top: 15px;
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid #ebeef5;

  ::v-deep .el-table {
    border-radius: 4px;

    &::before {
      display: none;
    }

    th {
      background-color: #f2f6fc !important;
      font-weight: 500;
      color: #333;
      padding: 12px 0;
      border-bottom: 1px solid #ebeef5;
    }

    td {
      padding: 10px 0;
      border-bottom: 1px solid #ebeef5;
    }
  }

  ::v-deep .el-table__row {
    transition: background-color 0.2s;
  }
}

.tree-node-name {
  display: inline-flex !important;
  align-items: center;
  vertical-align: middle;

  .node-icon {
    margin-right: 8px;
    font-size: 16px;

    // 文件夹图标 - 商务黄色
    &.el-icon-folder {
      color: #E6A23C;
    }

    // 文档图标 - 与需求页面保持一致
    &.el-icon-document {
      color: #409EFF;
    }
  }
}

// 父节点样式 - 商务风格
.parent-node {
  font-weight: 500;
  background-color: #fafafa;

  ::v-deep td {
    border-bottom: 1px solid #e0e3e9 !important;
  }
}

// 操作区域按钮样式优化 - 更加商务化
.table-button {
  padding: 4px 6px;
  margin: 0 3px;
  transition: all 0.2s;
  font-size: 12px;
  border-radius: 2px;
  background-color: transparent;
  border: 1px solid transparent;

  &.edit {
    color: #0960bd;

    &:hover {
      color: #0960bd;
      background-color: rgba(9, 96, 189, 0.08);
      border-color: rgba(9, 96, 189, 0.2);
    }
  }

  &.add {
    color: #18a058;

    &:hover {
      color: #18a058;
      background-color: rgba(24, 160, 88, 0.08);
      border-color: rgba(24, 160, 88, 0.2);
    }
  }

  &.delete {
    color: #d03050;

    &:hover {
      color: #d03050;
      background-color: rgba(208, 48, 80, 0.08);
      border-color: rgba(208, 48, 80, 0.2);
    }
  }
}

// 顶部操作按钮组样式 - 商务风格
.action-button {
  font-weight: 400;
  border-radius: 3px;
  transition: all 0.2s;
  padding: 8px 15px;
  margin-right: 10px;
  font-size: 12px;

  i {
    margin-right: 4px;
  }
}

.add-btn {
  background-color: #0960bd;
  border: 1px solid #0960bd;
  color: #fff;

  &:hover {
    background-color: #0854a9;
    border-color: #0854a9;
  }
}

.expand-btn {
  background-color: #f2f3f5;
  border: 1px solid #dcdfe6;
  color: #606266;

  &:hover {
    background-color: #e9ebef;
    color: #333;
  }
}

.search-btn {
  background-color: #0960bd;
  border: 1px solid #0960bd;
  color: #fff;
  padding: 8px 15px;
  border-radius: 3px;
  font-size: 12px;

  &:hover, &:focus {
    background-color: #0854a9;
    border-color: #0854a9;
  }
}

.reset-btn {
  border-radius: 3px;
  padding: 8px 15px;
  border: 1px solid #dcdfe6;
  background-color: #f2f3f5;
  color: #606266;
  font-size: 12px;

  &:hover, &:focus {
    background-color: #e9ebef;
    color: #333;
  }
}

// 对话框样式优化 - 商务风格
.struct-dialog {
  ::v-deep .el-dialog {
    border-radius: 4px;
    overflow: hidden;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);

    .el-dialog__header {
      border-bottom: 1px solid #ebeef5;
      padding: 16px 20px;
      background: #fafbfc;
    }

    .el-dialog__title {
      font-size: 16px;
      font-weight: 500;
      color: #303133;
    }

    .el-dialog__headerbtn {
      top: 16px;
    }

    .el-dialog__body {
      padding: 30px 30px 10px;
    }

    .el-dialog__footer {
      border-top: 1px solid #ebeef5;
      padding: 14px 20px;
    }

    .el-form-item__label {
      padding-right: 15px;
      font-weight: 500;
    }

    .el-input__inner,
    .el-textarea__inner {
      padding: 0 15px;
      height: 38px;
      line-height: 38px;
    }

    .el-textarea__inner {
      padding: 10px 15px;
      height: auto;
      line-height: 1.5;
    }

    .vue-treeselect__control {
      border-radius: 3px;
    }
  }
}

.dialog-btn {
  border-radius: 3px;
  padding: 8px 20px;
  font-weight: 400;
  font-size: 13px;
}

.submit-btn {
  background-color: #0960bd;
  border-color: #0960bd;
  color: #fff;

  &:hover {
    background-color: #0854a9;
    border-color: #0854a9;
  }
}

.cancel-btn {
  background-color: #f2f3f5;
  border-color: #dcdfe6;
  color: #606266;

  &:hover, &:focus {
    background-color: #e9ebef;
    color: #333;
  }
}

// 相关数据标签优化 - 商务风格
.related-data {
  display: flex;
  justify-content: center;
  gap: 6px;

  .data-tag {
    cursor: default;
    border-radius: 2px;
    padding: 3px 6px;
    font-size: 11px;
  }
}

// 操作列固定并优化样式
::v-deep .fixed-width {
  .cell {
    display: flex;
    justify-content: center;
    padding: 0 10px;

    .table-button {
      margin: 0 4px;
      white-space: nowrap;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      height: 24px;

      i {
        font-size: 14px;
        margin-right: 3px;
      }
    }
  }
}

// 表格操作區域優化 - 商務風格鏈接
.table-operation {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: nowrap;
  white-space: nowrap;

  &.full-width {
    width: 100%;
    padding: 0 10px;
    box-sizing: border-box;
    display: flex;
    justify-content: space-evenly;
  }

  .link-text {
    font-size: 13px;
    text-decoration: none;
    cursor: pointer;
    padding: 2px 4px;
    transition: all 0.2s;

    i {
      margin-right: 2px;
      font-size: 12px;
    }

    &:hover {
      text-decoration: underline;
    }
  }

  .link-divider {
    margin: 0 5px;
    color: #DCDFE6;
  }

  .empty-placeholder {
    width: 45px;
    display: inline-block;
  }

  .edit-link {
    color: #409EFF;

    &:hover {
      color: #66b1ff;
    }
  }

  .add-link {
    color: #18a058;

    &:hover {
      color: #42c782;
    }
  }

  .delete-link {
    color: #d03050;

    &:hover {
      color: #e16b84;
    }
  }
}

// 操作列固定樣式優化
::v-deep .operation-column {
  padding: 0;
}

// 树形表格缩进和展开图标样式优化
::v-deep .el-table__body {
  .el-table__row {
    // 展开/折叠图标样式
    .el-table__expand-icon {
      display: inline-flex;
      align-items: center;
      margin-right: 8px;

      .el-icon-arrow-right {
        transition: transform 0.3s;
      }

      &.el-table__expand-icon--expanded {
        .el-icon-arrow-right {
          transform: rotate(90deg);
        }
      }
    }

    // 缩进样式
    .el-table__indent {
      padding-left: 20px !important;
    }
  }
}

// 挂载数据区域样式
.mount-data {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
}

// 挂载链接样式
.mount-links {
  display: flex;
  justify-content: center;
  gap: 5px;
  flex-wrap: wrap;
  margin-top: 5px;
}

.mount-link {
  color: #18a058;

  &:hover {
    color: #42c782;
  }
}

.mount-link-tech {
  color: #0960bd;

  &:hover {
    color: #409EFF;
  }
}

/* 挂载需求对话框样式 */
.demand-dialog {
  min-width: 900px;
}

.dialog-container {
  padding: 10px;
}

.dialog-target {
  margin-bottom: 20px;
  padding: 15px;
  background-color: #f9f9f9;
  border-radius: 4px;
  border-left: 3px solid #409EFF;
}

.target-label {
  font-weight: bold;
  margin-right: 10px;
  color: #606266;
}

.target-node {
  font-size: 16px;
  color: #303133;
  font-weight: 500;
}

.dialog-content {
  height: 65vh;
  min-height: 500px;
  margin-bottom: 20px;
}

.tree-container, .table-container {
  height: 100%;
}

.panel-container {
  border: 1px solid #EBEEF5;
  border-radius: 4px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
  margin-bottom: 20px;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.panel-header {
  font-size: 16px;
  font-weight: bold;
  color: #303133;
  padding: 15px;
  border-bottom: 1px solid #e6e6e6;
  background-color: #fafafa;
  border-radius: 4px 4px 0 0;
}

.panel-body {
  padding: 15px;
  flex: 1;
  overflow: auto;
}

.search-box {
  padding: 15px 15px 0;
}

/* 对话框按钮样式 */
.dialog-btn {
  padding: 10px 20px;
  font-weight: 500;
  transition: all 0.3s;
}

.submit-btn {
  box-shadow: 0 2px 4px rgba(64, 158, 255, 0.2);

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(64, 158, 255, 0.3);
  }
}

.cancel-btn:hover {
  transform: translateY(-2px);
}

/* 树状结构样式 */
.el-tree {
  background-color: transparent;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  padding: 10px;
}

/* 高亮选中的节点 */
.el-tree-node.is-current > .el-tree-node__content {
  background-color: #ecf5ff;
  color: #409EFF;
}

/* 树节点样式 */
.tree-node-name {
  display: inline-flex !important;
  align-items: center;
  vertical-align: middle;
}

.node-icon {
  margin-right: 8px;
  font-size: 16px;
}

/* 文件夹图标 - 黄色 */
.el-icon-folder {
  color: #E6A23C;
}

/* 文档图标 - 蓝色 */
.el-icon-document {
  color: #409EFF;
}

.operation-column {
  /* border-left: 1px solid #ebeef5; 移除左侧边框 */
}

/* 选项容器样式 */
.options-container {
  display: flex;
  align-items: center;
  cursor: pointer;
}

/* 选项数量标签样式 */
.option-count-tag {
  background-color: #f5f7fa;
  color: #606266;
  border-color: #e4e7ed;
  font-weight: normal;
  padding: 3px 8px;
  transition: all 0.2s;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.option-count-tag:hover {
  background-color: #eef1f6;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
}

/* 文本值样式 */
.demand-text {
  color: #303133;
  font-size: 13px;
}

/* 选项提示窗口样式 */
.option-tooltip {
  max-width: 300px;
  line-height: 1.8;
  white-space: pre-wrap;
  background: #ffffff;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.12);
  border: none;
  padding: 12px 16px;
  border-radius: 4px;
  font-size: 13px;
  color: #303133;
}

/* 内容容器通用样式 */
.content-container,
.options-container {
  display: flex;
  align-items: center;
  cursor: pointer;
}

/* 标签通用样式 */
.text-content-tag,
.option-count-tag {
  font-weight: normal;
  padding: 3px 8px;
  transition: all 0.2s;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

/* 文本标签样式 */
.text-content-tag {
  background-color: #ecf5ff;
  color: #409eff;
  border-color: #d9ecff;
}

.text-content-tag:hover {
  background-color: #d9ecff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
}

/* 选项标签样式 */
.option-count-tag {
  background-color: #f5f7fa;
  color: #606266;
  border-color: #e4e7ed;
}

.option-count-tag:hover {
  background-color: #eef1f6;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
}

/* 空值样式 */
.empty-value {
  color: #909399;
  font-style: italic;
  font-size: 13px;
  font-family: inherit;
}

/* 操作列样式 */
.operation-column {
  /* border-left: 1px solid #ebeef5; 移除左侧边框 */
}

/* 编辑按钮深蓝色样式 */
.edit-text-btn {
  color: #0960bd;
}

.edit-text-btn:hover {
  color: #409EFF;
}

/* 移除按钮暗红色样式 */
.delete-text-btn {
  color: #d03050;
}

.delete-text-btn:hover {
  color: #f56c6c;
}

/* 增加表单项间距 */
.form-item-spaced {
  margin-bottom: 30px !important;
}

::v-deep .el-form-item {
  margin-bottom: 30px;
}

::v-deep .el-form-item:last-child {
  margin-bottom: 20px;
}

::v-deep .el-dialog__body {
  padding: 30px 30px 15px;
}

.range-container {
  display: inline-flex;
  align-items: center;

  .range-content {
    font-family: monospace;
    color: #606266;
  }
}

.el-input-number {
  width: 100%;
}

/* 统一值显示样式 */
.text-container, .range-container, .options-container {
  display: inline-flex;
  align-items: center;
  min-height: 22px;

  .text-content, .range-content {
    color: #606266;
    font-size: 13px;
    font-family: inherit; /* 使用继承的字体，确保一致性 */
    word-break: break-all;
  }

  .option-count-tag {
    font-size: 12px;
    padding: 0 6px;
    height: 22px;
    line-height: 20px;

    i {
      margin-right: 3px;
    }
  }
}

/* 内容提示样式 */
.content-tooltip {
  max-width: 300px;
  line-height: 1.5;
  font-family: inherit;
}

/* 添加新的样式 */
.range-edit-item {
  margin-bottom: 15px;

  .range-input-row {
    display: flex;
    align-items: center;
  }

  .range-number-input {
    width: 100%;
  }

  .remove-range-btn {
    margin-left: 10px;
  }
}

.range-actions {
  margin-top: 15px;
  text-align: center;

  .add-range-btn {
    width: 120px;
  }
}

.value-container {
  .option-count-tag {
    background-color: #f5f7fa;
    color: #606266;
    border-color: #e4e7ed;

    &:hover {
      background-color: #eef1f6;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
    }

    i {
      margin-right: 3px;
    }
  }
}

/* 值显示区域的统一样式 */
.value-wrapper {
  display: inline-flex;
  align-items: center;
  background-color: #f5f7fa;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 0 8px;
  min-height: 24px;

  .text-value, .count-value {
    color: #606266;
    font-size: 13px;
    line-height: 1.4;

    i {
      margin-right: 4px;
    }
  }

  .empty-value {
    color: #909399;
    font-style: italic;
  }

  &:hover {
    background-color: #eef1f6;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
  }
}

/* 移除旧的不一致样式 */
.text-container, .options-container, .value-container {
  display: none; /* 或者完全删除这些类 */
}

// 新增样式
.extract-btn {
  background-color: #67c23a;
  border-color: #67c23a;
  color: #fff;

  &:hover {
    background-color: #85ce61;
    border-color: #85ce61;
  }
}

.extract-dialog {
  .dialog-container {
    display: flex;
    flex-direction: column;
    min-height: 300px;
  }

  .upload-container {
    padding: 20px 0;
  }

  .no-results-tip {
    padding: 20px 0;
    display: flex;
    justify-content: center;
    align-items: center;

    p {
      color: #909399;
      font-size: 14px;
      margin-top: 10px;
    }
  }

  .extraction-results {
    margin-top: 20px;
    border: 1px solid #ebeef5;
    border-radius: 4px;
    padding: 15px;
    background-color: #f9f9f9;

    .result-header {
      display: flex;
      justify-content: space-between;
      align-items: center;

      h3 {
        margin: 0;
        font-size: 16px;
        color: #303133;
      }

      .result-actions {
        display: flex;
        gap: 10px;
      }
    }
  }
}

.text-input-container {
  margin: 20px 0;

  .el-textarea {
    margin-bottom: 10px;
  }

  .text-input-tip {
    color: #909399;
    font-size: 13px;
    line-height: 1.5;
  }
}

// 添加文件预览样式
.file-preview {
  margin-top: 20px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 15px;
  background-color: #fff;

  .preview-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
    padding-bottom: 10px;
    border-bottom: 1px solid #ebeef5;

    span {
      color: #606266;
      font-size: 14px;
      font-weight: 500;
    }

    .preview-info {
      color: #909399;
      font-size: 13px;
    }
  }

  .preview-content {
    ::v-deep .el-textarea__inner {
      background-color: #f8f9fa;
      font-family: 'Courier New', Courier, monospace;
      line-height: 1.6;
      padding: 10px;
    }
  }
}

// 标准选择区域样式
.standard-selection {
  margin: 15px 0;
  padding: 15px;
  background-color: #f9f9f9;
  border-radius: 4px;
  border-left: 3px solid #67c23a;

  .standard-header {
    display: flex;
    align-items: center;

    .standard-label {
      font-weight: bold;
      margin-right: 15px;
      color: #606266;
      min-width: 70px;
    }

    .check-btn {
      margin-left: 15px;
    }
  }
}

// 风险评估区域样式
.risk-assessment {
  margin-top: 20px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  background-color: #fff;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);

  .risk-header {
    padding: 15px;
    border-bottom: 1px solid #ebeef5;
    display: flex;
    justify-content: space-between;
    align-items: center;
    background-color: #f5f7fa;

    .risk-title {
      font-size: 16px;
      font-weight: bold;
      color: #303133;
    }
  }

  .risk-content {
    padding: 20px;
  }

  .risk-summary {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    grid-gap: 15px;
    margin-bottom: 20px;

    .summary-item {
      .summary-label {
        font-weight: 500;
        color: #606266;
        margin-right: 8px;
      }

      .summary-value {
        color: #303133;

        &.result-high {
          color: #f56c6c;
          font-weight: bold;
        }

        &.result-medium {
          color: #e6a23c;
          font-weight: bold;
        }

        &.result-low {
          color: #909399;
        }

        &.result-safe {
          color: #67c23a;
        }
      }
    }
  }

  .risk-details {
    .risk-item {
      margin-bottom: 15px;
      padding: 15px;
      border-radius: 4px;
      border-left: 4px solid #dcdfe6;
      background-color: #f8f9fa;

      &.risk-level-high {
        border-left-color: #f56c6c;
        background-color: #fef0f0;
      }

      &.risk-level-medium {
        border-left-color: #e6a23c;
        background-color: #fdf6ec;
      }

      &.risk-level-low {
        border-left-color: #909399;
        background-color: #f4f4f5;
      }

      &.risk-level-safe {
        border-left-color: #67c23a;
        background-color: #f0f9eb;
      }

      .risk-item-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 10px;

        .risk-indicator-name {
          font-weight: bold;
          color: #303133;
          font-size: 14px;
        }
      }

      .risk-item-value, .risk-item-standard {
        margin-bottom: 8px;
        font-size: 13px;

        .value-label, .standard-label {
          color: #606266;
          margin-right: 8px;
        }

        .value-content, .standard-content {
          color: #303133;
          font-family: 'Courier New', monospace;
        }
      }

      .risk-analysis {
        margin-top: 10px;
        color: #606266;
        font-size: 13px;
        line-height: 1.6;
      }
    }
  }

  .risk-suggestions {
    .suggestion-item {
      display: flex;
      margin-bottom: 10px;

      .suggestion-number {
        width: 24px;
        height: 24px;
        border-radius: 50%;
        background-color: #409eff;
        color: white;
        display: flex;
        justify-content: center;
        align-items: center;
        margin-right: 10px;
        flex-shrink: 0;
      }

      .suggestion-content {
        color: #606266;
        font-size: 14px;
        line-height: 1.6;
      }
    }
  }

  .no-suggestions {
    padding: 15px;
    text-align: center;
    color: #67c23a;
    background-color: #f0f9eb;
    border-radius: 4px;
  }
}

.custom-standard-info {
  margin-top: 15px;
  padding: 12px;
  background-color: #f0f9eb;
  border-radius: 4px;
  border-left: 3px solid #67c23a;

  .standard-file-info {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 10px;

    .file-name {
      font-weight: 500;
      color: #303133;
    }

    .file-size {
      color: #909399;
      font-size: 12px;
    }

    .el-tag {
      margin-left: 10px;
    }
  }

  .standard-actions {
    display: flex;
    gap: 15px;
    margin-top: 8px;

    .el-button {
      padding: 6px 12px;
      font-size: 12px;
    }
  }
}

/* 自定义标准相关样式 */
.standard-divider {
  margin: 0 15px;
  color: #909399;
}

.custom-standard-upload {
  display: inline-block;
  margin-right: 15px;
}

.standard-content-container {
  padding: 10px;
}

.standard-content-viewer {
  ::v-deep .el-textarea__inner {
    background-color: #f8f9fa;
    font-family: 'Courier New', Courier, monospace;
    line-height: 1.6;
    padding: 10px;
  }
}
</style>

<style>
/* 内容提示框全局样式 */
.content-tooltip {
  max-width: 350px !important;
  padding: 12px 16px !important;
  border-radius: 4px !important;
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.15) !important;
  border: none !important;
  font-size: 13px !important;
  color: #303133 !important;
  background: #ffffff !important;
  line-height: 1.6 !important;
  white-space: pre-wrap !important;
}
</style>


